package com.sduept.nwld.dataserver.controller.equipment.assessment;

import com.alibaba.fastjson.JSONObject;
import com.sduept.bigdata.equipment.assessment.enums.SubStationTypeEnum;
import com.sduept.bigdata.equipment.assessment.exception.ParameterException;
import com.sduept.bigdata.equipment.assessment.model.inspection.InspectionExpert;
import com.sduept.bigdata.equipment.assessment.model.inspection.InspectionItem;
import com.sduept.bigdata.equipment.assessment.model.inspection.InspectionStation;
import com.sduept.bigdata.equipment.assessment.model.standardlib.StandardInspection;
import com.sduept.bigdata.equipment.assessment.model.template.AssessmentTemplate;
import com.sduept.bigdata.equipment.assessment.model.template.AssessmentTemplateItem;
import com.sduept.bigdata.equipment.assessment.service.AssessmentTemplateService;
import com.sduept.bigdata.equipment.assessment.service.InspectionExpertService;
import com.sduept.bigdata.equipment.assessment.service.InspectionItemService;
import com.sduept.cim.ledger.excetpion.ManagementUnitException;
import com.sduept.cim.ledger.manager.SubstationLedgerManager;
import com.sduept.cim.ledger.model.ManagementUnitDict;
import com.sduept.cim.ledger.model.SubstationLedger;
import com.sduept.cim.ledger.services.ManagementUnitService;
import com.sduept.cim.model.core.Substation;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import com.sduept.bigdata.weather.map.MapDataCache;
import com.sduept.permission.entity.DepartmentEntityBean;
import com.sduept.permission.entity.PersonnelEntityBean;
import com.sduept.permission.manager.DepartManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.primefaces.PrimeFaces;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.NodeUnselectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.*;
/**
 * 
 * @author pengz
 *
 */
@Slf4j
@Named
@ViewScoped
public class SelectFromTemplateController extends AbstractController{

	private static final long serialVersionUID = -4402923877268951841L;
	@Inject
	private AssessmentTemplateService templateService;
	@Inject
	private InspectionItemService itemService;
	@Inject
	private ManagementUnitService unitService;
	@Inject
	private DepartManager dm;
	@Inject
	private InspectionExpertService expertService;
	@Inject
	private SubstationLedgerManager stationLedgerM;
	@Inject
	private MapDataCache cc;
	/**
	 * 传递的参数：计划开始时间
	 */
	private Date startTime;
	/**
	 * 传递的参数：计划结束时间
	 */
	private Date endTime;
	/**
	 * 传递的参数：评价计划id
	 */
	private String planId;
	/**
	 * 所有可获得的模板集合
	 */
	private List<AssessmentTemplate> templateList = new ArrayList<AssessmentTemplate>();
	/**
	 * 选中的模板id
	 */
	private String selectedTempletId;
	/**
	 * key:变电站
	 * value：评价标准
	 */
	private Map<String,List<InspectionItem>> stationIdToInspectionItems = new HashMap<String, List<InspectionItem>>();
	/**
	 * key:顶级运维部门id
	 * value:专家集合
	 */
	private Map<String,List<InspectionExpert>> deptIdToExperts = new HashMap<String, List<InspectionExpert>>();
	/**
	 * 选中模板中所有的变电站
	 */
	private List<Substation> stationAll = new ArrayList<Substation>();
	
	private List<Substation> substations = new ArrayList<Substation>();

	/**
	 * 
	 */
	Map<String,List<Substation>> scopeIdToSubstations = new HashMap<String, List<Substation>>();

	/**
	 * 保存变电站id选中的专家
	 */
	Map<String, List<InspectionExpert>> stationIdToExperts = new HashMap<String, List<InspectionExpert>>();
	
	/**
	 * 变电站树根节点
	 */
	private TreeNode stationRoot;
	/**
	 * 选中的变电站节点
	 */
	private TreeNode[] selectedStationNodes;
	/**
	 * 部门id对应选中的变电站
	 */
	private Map<String,List<Substation>> deptIdToSelectedSubstations = new HashMap<String, List<Substation>>();
	/**
	 * 专家树根节点
	 */
	private TreeNode expertRoot;
	/**
	 * 选中的专家节点
	 */
	private TreeNode[] selectedExpertNodes;
	/**
	 * 部门id对应选中的专家
	 */
	private Map<String,List<InspectionExpert>> deptIdToSelectedExperts = new HashMap<String, List<InspectionExpert>>();

	//默认 1位专家/站
	private int expertNum = 1;
	/**
	 * 一键分配，默认选中
	 */
	private boolean auto = true;
	/**
	 * 手动分配
	 */
	private boolean manual = false;
	/**
	 * 所有的检修范围
	 */
	private Map<String,ManagementUnitDict> maintenanceScopesMap = new HashMap<String, ManagementUnitDict>();
	/**
	 * 设备台账-运维单位名称缓存
	 */
	private Map<String,String> ledgerIdToMaintenanceUnitName = new HashMap<String, String>();
	/**
	 * 运维单位名称-检修范围缓存
	 */
	private Map<String,ManagementUnitDict> maintenanceUnitNameToScope = new HashMap<String, ManagementUnitDict>();
	/**
	 * 所有的变电站map
	 */
	private Map<String, Substation> stationMap = new HashMap<String, Substation>();
	/**
	 * 从模板中选择的变电站对应的变电站类型（根据选择的评价标准获得）
	 */
	private Map<String,SubStationTypeEnum> stationIdToType = new HashMap<String, SubStationTypeEnum>();
	/**
	 * 需要返回的数据：
	 * 
	 */
	private String data = "";
	@PostConstruct
	public void init() {
		initParamters();
		PersonnelEntityBean user = getCurrentUser();
		try {
			templateList = findAvailableTemplatesByPerson(user);
		} catch (Exception e) {
			e.printStackTrace();
		}
		initExpertRoot();
		preGenerateStationTree();
	}
	/**
	 * 初始化传递的参数
	 */
	private void initParamters() {
		
	}
	/**
	 * 生成变电站树前的准备工作
	 */
	private void preGenerateStationTree() {
		stationMap = cc.getStationid_map();
		try {
			List<ManagementUnitDict> allMaintenances = unitService.getAllMaintenanceScopes();
			for (ManagementUnitDict unit : allMaintenances) {
				maintenanceScopesMap.put(unit.getId(), unit);
			}
			initStationAndMaintenanceUnitMap();
		} catch (ManagementUnitException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 初始化ledgerIdToMaintenanceUnitName
	 */
	private void initStationAndMaintenanceUnitMap() {
		List<SubstationLedger> ledgers = stationLedgerM.findAllSubstationLedger();
		try {
			for (SubstationLedger ledger : ledgers) {
				String maintenanceUnitName = ledger.getMaintenanceUnit();
				if(StringUtils.isNotBlank(maintenanceUnitName)) {
					ledgerIdToMaintenanceUnitName.put(ledger.getCimId(), maintenanceUnitName);
					ManagementUnitDict maintenanceUnit = unitService.getManagementUnitByName(maintenanceUnitName);
					if(maintenanceUnit!=null&&StringUtils.isNotBlank(maintenanceUnit.getPid())) {
						if(!maintenanceUnitNameToScope.containsKey(maintenanceUnitName)) {
							//运维单位的父单位是检修范围
							ManagementUnitDict scope = null;
							if(maintenanceScopesMap.containsKey(maintenanceUnit.getPid())) {
								scope = maintenanceScopesMap.get(maintenanceUnit.getPid());
							}
//							ManagementUnitDict parent = unitService.getManagementUnit(maintenanceUnit.getPid());
							maintenanceUnitNameToScope.put(maintenanceUnitName, scope);
						}
					}
					
				}
			}
		} catch (ManagementUnitException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 根据用户权限返回可用的模板集合
	 * @param user
	 * @return
	 * @throws Exception 
	 */
	private List<AssessmentTemplate> findAvailableTemplatesByPerson(PersonnelEntityBean user) throws Exception {
		String userId = null;
		List<AssessmentTemplate> personalTemplates = new ArrayList<AssessmentTemplate>();
		if(null != user) {
			userId = user.getId();
			personalTemplates = templateService.findPersonalAssessmentTemplateByUserId(userId);			
		}
		List<AssessmentTemplate> publicTemplates = templateService.findPublicTemplates();
		publicTemplates.addAll(personalTemplates);
		return publicTemplates;
				
	}
	/**
	 * 初始化专家树根节点
	 */
	private void initExpertRoot() {
		expertRoot = new DefaultTreeNode();
		List<DepartmentEntityBean> rootDepts = dm.findRootDepts();
		if (rootDepts.size() == 0) {
			return ;
		}
		// 组织机构的根节点，即南方电网
		DepartmentEntityBean rootDept = rootDepts.get(0);
		DefaultTreeNode root = new DefaultTreeNode("dept", rootDept, expertRoot);
		List<DepartmentEntityBean> departments = dm.getDepartmentsByParent(rootDept.getId());
		for (DepartmentEntityBean departmentEntityBean : departments) {
			DefaultTreeNode pdeptNode = new DefaultTreeNode("dept",departmentEntityBean,root);
			addExpertNode(departmentEntityBean.getId(),departmentEntityBean,pdeptNode);
			if(auto) {
				pdeptNode.setSelectable(false);
			}
		}
		root.setExpanded(true);
		if(auto) {
			root.setSelectable(false);
		}
	}
	/**
	 * 添加专家节点
	 * @param id
	 * @param pdept
	 * @param pdeptNode
	 */
	private void addExpertNode(String id, DepartmentEntityBean pdept, DefaultTreeNode pdeptNode) {
		if(!deptIdToExperts.containsKey(id)) {
			deptIdToExperts.put(id, new ArrayList<InspectionExpert>());
		}
		List<InspectionExpert> experts = expertService.findByDeptName(pdept.getName());
		if(experts!=null&&!experts.isEmpty()) {
			for (InspectionExpert inspectionExpert : experts) {
				DefaultTreeNode node = new DefaultTreeNode("expert",inspectionExpert,pdeptNode);
				if(auto) {
					node.setSelectable(false);
				}
			}
			deptIdToExperts.get(id).addAll(experts);
		}
		//该部门下的所有子部门
		List<DepartmentEntityBean> children = dm.getDepartmentsByParent(pdept.getId());
		if(children!=null&&!children.isEmpty()) {
			for (DepartmentEntityBean dept : children) {
				addExpertNode(id,dept,pdeptNode);
			}
		}
		
	}
	/**
	 * 处理专家树节点选中事件
	 * @param event
	 */
	public void onExpertNodeSelect(NodeSelectEvent event) {
		TreeNode selectedExpertNode = event.getTreeNode();
		if("deptRoot".equals(selectedExpertNode.getType())) {//一级节点（南方电网）
			deptIdToSelectedExperts.clear();
			deptIdToSelectedExperts.putAll(deptIdToExperts);
			for(TreeNode deptNode : selectedExpertNode.getChildren()) {
				deptNode.setSelected(true);
				for(TreeNode node : deptNode.getChildren()) {
					node.setSelected(true);
				}
			}
		}else if("dept".equals(selectedExpertNode.getType())) {
			DepartmentEntityBean dept = (DepartmentEntityBean) selectedExpertNode.getData();
			if(deptIdToSelectedExperts.containsKey(dept.getId())) {
				deptIdToSelectedExperts.remove(dept.getId());
			}
			deptIdToSelectedExperts.put(dept.getId(), deptIdToExperts.get(dept.getId()));
			for(TreeNode node : selectedExpertNode.getChildren()) {
				node.setSelected(true);
			}
		}else {
			InspectionExpert expert = (InspectionExpert) selectedExpertNode.getData();
			TreeNode deptNode = selectedExpertNode.getParent();
			DepartmentEntityBean dept = (DepartmentEntityBean) deptNode.getData();
			if(!deptIdToSelectedExperts.containsKey(dept.getId())) {
				deptIdToSelectedExperts.put(dept.getId(), new ArrayList<InspectionExpert>());
			}
			deptIdToSelectedExperts.get(dept.getId()).add(expert);
		}
	}
	/**
	 * 处理专家树节点取消选择事件
	 * @param event
	 */
	public void onExpertNodeUnSelect(NodeUnselectEvent event) {
		TreeNode selectedExpertNode = event.getTreeNode();
		if("deptRoot".equals(selectedExpertNode.getType())) {//一级节点（南方电网）
			deptIdToSelectedExperts.clear();
			for(TreeNode deptNode : selectedExpertNode.getChildren()) {
				deptNode.setSelected(false);
				for(TreeNode node : deptNode.getChildren()) {
					node.setSelected(false);
				}
			}
		}else if("dept".equals(selectedExpertNode.getType())) {
			DepartmentEntityBean dept = (DepartmentEntityBean) selectedExpertNode.getData();
			if(deptIdToSelectedExperts.containsKey(dept.getId())) {
				deptIdToSelectedExperts.remove(dept.getId());
			}
			for(TreeNode node : selectedExpertNode.getChildren()) {
				node.setSelected(false);
			}
		}else {
			InspectionExpert expert = (InspectionExpert) selectedExpertNode.getData();
			TreeNode deptNode = selectedExpertNode.getParent();
			DepartmentEntityBean dept = (DepartmentEntityBean) deptNode.getData();
			deptIdToSelectedExperts.get(dept.getId()).remove(expert);
		}
	}
	/**
	 * 模板选中处理事件
	 */
	public void handleTempletSelect() {
		stationIdToInspectionItems.clear();
		stationAll.clear();
		substations.clear();
		scopeIdToSubstations.clear();
		deptIdToSelectedSubstations.clear();
		deptIdToSelectedExperts.clear();
		stationIdToExperts.clear();
		Set<AssessmentTemplateItem> tempItems = templateService.findAssessmentTemplateItemByAssessmentTemplateId(selectedTempletId);
		if(tempItems!=null&&!tempItems.isEmpty()) {
			for (AssessmentTemplateItem templateItem : tempItems) {
				Substation station = stationMap.get(templateItem.getSubstationid());
				stationAll.add(station);
				List<StandardInspection> stands;
				try {
					stands = templateService.findStandardInspectionbyItem(templateItem.getId());
					if(!stands.isEmpty()) {
						StandardInspection standRoot = stands.get(0);
						if(standRoot.getStationType()!=null) {
							stationIdToType.put(station.getId(), standRoot.getStationType());
						}
					}
				} catch (Exception e1) {
					e1.printStackTrace();
				}
				try {
					List<InspectionItem> inspectionItems = itemService.convertFromAssessmentTemplateItem(templateItem.getId(),planId);
					stationIdToInspectionItems.put(station.getId(), inspectionItems);
				} catch (ParameterException e) {
					e.printStackTrace();
				}
			}
		}
		initStationTree();
		if(auto) {
			setExpertTreeNodeSelectable(false);
		}else {
			setExpertTreeNodeSelectable(true);
		}
	}
	
	/**
	 * 初始化变电站树：
	 * 南方电网---检修范围---运维单位---变电站
	 * 实现方式：变电站--》运维单位---》检修范围
	 */
	private void initStationTree() {
		long start = System.currentTimeMillis();
		stationRoot = new DefaultTreeNode();
		String deptRootName = "";
		try {
			deptRootName = unitService.getManagementUnitRoot();
		} catch (ManagementUnitException e) {
			e.printStackTrace();
		}
		DefaultTreeNode deptRoot = new DefaultTreeNode("deptRoot", deptRootName, stationRoot);
		// 南方电网下一级节点
		Map<String,TreeNode> secondLevelNodeMap = new HashMap<String, TreeNode>();
		for(Substation station : stationAll) {
			//获得该变电站的运维单位名称
			String unitName = ledgerIdToMaintenanceUnitName.get(station.getId());
			if(StringUtils.isNotBlank(unitName)) {
				if(maintenanceUnitNameToScope.containsKey(unitName)) {
					ManagementUnitDict scope = maintenanceUnitNameToScope.get(unitName);
					if(scope!=null) {
						if(!secondLevelNodeMap.containsKey(scope.getId())) {
							DefaultTreeNode secondLevelNode = new DefaultTreeNode("dept",scope,deptRoot);
							if(auto) {
								secondLevelNode.setSelectable(false);
							}
							secondLevelNodeMap.put(scope.getId(), secondLevelNode);
						}
						DefaultTreeNode node = new DefaultTreeNode("station",station,secondLevelNodeMap.get(scope.getId()));
						if(auto) {
							node.setSelectable(false);
						}
						if(!scopeIdToSubstations.containsKey(scope.getId())) {
							scopeIdToSubstations.put(scope.getId(), new ArrayList<Substation>());
						}
						scopeIdToSubstations.get(scope.getId()).add(station);
						substations.add(station);
//					}else {
//						if(!secondLevelNodeMap.containsKey("other")) {
//							DefaultTreeNode secondLevelNode = new DefaultTreeNode("dept","其他",deptRoot);
//							if(auto) {
//								secondLevelNode.setSelectable(false);
//							}
//							secondLevelNodeMap.put("other", secondLevelNode);
//						}
//						DefaultTreeNode node = new DefaultTreeNode("station",station,secondLevelNodeMap.get("other"));
//						if(auto) {
//							node.setSelectable(false);
//						}
					}
				}
			}
		}
		deptRoot.setExpanded(true);
		if(auto) {
			deptRoot.setSelectable(false);
		}
		long end = System.currentTimeMillis();
		log.info("use time : "+(end-start));
	}
	
	/**
	 * 处理变电站选中事件
	 * @param event
	 */
	public void onStationNodeSelect(NodeSelectEvent event) {
		TreeNode selectedStationNode = event.getTreeNode();
		if("deptRoot".equals(selectedStationNode.getType())) {
			deptIdToSelectedSubstations.clear();
			deptIdToSelectedSubstations.putAll(scopeIdToSubstations);
			for(TreeNode deptNode : selectedStationNode.getChildren()) {
				deptNode.setSelected(true);
				for(TreeNode node : deptNode.getChildren()) {
					node.setSelected(true);
				}
			}
		}else if("dept".equals(selectedStationNode.getType())) {
			ManagementUnitDict dept = (ManagementUnitDict) selectedStationNode.getData();
			if(deptIdToSelectedSubstations.containsKey(dept.getId())) {
				deptIdToSelectedSubstations.remove(dept.getId());
			}
			deptIdToSelectedSubstations.put(dept.getId(), scopeIdToSubstations.get(dept.getId()));
			for(TreeNode node : selectedStationNode.getChildren()) {
				node.setSelected(true);
			}
		}else {
			Substation station = (Substation) selectedStationNode.getData();
			TreeNode deptNode = selectedStationNode.getParent();
			ManagementUnitDict dept = (ManagementUnitDict) deptNode.getData();
			if(!deptIdToSelectedSubstations.containsKey(dept.getId())) {
				deptIdToSelectedSubstations.put(dept.getId(), new ArrayList<Substation>());
			}
			deptIdToSelectedSubstations.get(dept.getId()).add(station);
		}
	}
	/**
	 * 处理变电站取消选择事件
	 * @param event
	 */
	public void onStationNodeUnSelect(NodeUnselectEvent event) {
		TreeNode selectedStationNode = event.getTreeNode();
		if("deptRoot".equals(selectedStationNode.getType())) {
			deptIdToSelectedSubstations.clear();
			for(TreeNode deptNode : selectedStationNode.getChildren()) {
				deptNode.setSelected(false);
				for(TreeNode node : deptNode.getChildren()) {
					node.setSelected(false);
				}
			}
		}else if("dept".equals(selectedStationNode.getType())) {
			ManagementUnitDict dept = (ManagementUnitDict) selectedStationNode.getData();
			deptIdToSelectedSubstations.remove(dept.getId());
			for(TreeNode node : selectedStationNode.getChildren()) {
				node.setSelected(false);
			}
		}else {
			Substation station = (Substation) selectedStationNode.getData();
			TreeNode deptNode = selectedStationNode.getParent();
			ManagementUnitDict dept = (ManagementUnitDict) deptNode.getData();
			deptIdToSelectedSubstations.get(dept.getId()).remove(station);
		}
	}
	/**
	 * 
	 * @param stationId
	 */
	public String getExpertListStr(String stationId) {
		StringBuffer result = new StringBuffer("");
		if(stationIdToExperts.containsKey(stationId)) {
			List<InspectionExpert> expertList = stationIdToExperts.get(stationId);
			if(!expertList.isEmpty()) {
				result.append("（");
				for (InspectionExpert inspectionExpert : expertList) {
					result.append(inspectionExpert.getName()).append(",");
				}
				result.deleteCharAt(result.length()-1);
				result.append("）");
			}
			
		}
		return result.toString();
	}

	/**
	 * 处理一键分配选择框change事件函数
	 */
	public void handleAuto() {
		if(auto) {
			manual = false;
			setStationTreeNodeSelectable(false);
			setExpertTreeNodeSelectable(false);
			
		}else {
			manual = true;
			setStationTreeNodeSelectable(true);
			setExpertTreeNodeSelectable(true);
		}
	}
	/**
	 * 处理手动分配选择框change事件函数
	 */
	public void handleManual() {
		if(manual) {
			auto = false;
			setStationTreeNodeSelectable(true);
			setExpertTreeNodeSelectable(true);
		}else {
			auto = true;
			setStationTreeNodeSelectable(false);
			setExpertTreeNodeSelectable(false);
		}
	}
	/**
	 * 设置专家树节点是否可选
	 * @param selectable
	 */
	private void setExpertTreeNodeSelectable(boolean selectable) {
		if(expertRoot!=null) {
			for(TreeNode root : expertRoot.getChildren()) {
				root.setSelectable(selectable);
				for(TreeNode deptNode : root.getChildren()) {
					deptNode.setSelectable(selectable);
					for(TreeNode expertNode : deptNode.getChildren()) {
						expertNode.setSelectable(selectable);
					}
				}
			}
		}
	}
	/**
	 * 设置选择变电站树节点是否可选
	 * @param selectable
	 */
	private void setStationTreeNodeSelectable(boolean selectable) {
		if(stationRoot!=null) {
			for(TreeNode root : stationRoot.getChildren()) {
				root.setSelectable(selectable);
				for(TreeNode deptNode : root.getChildren()) {
					deptNode.setSelectable(selectable);
					for(TreeNode node : deptNode.getChildren()) {
						node.setSelectable(selectable);
					}
				}
			}
		}
	}

	/**
	 * 分配按钮是否可用
	 * @return
	 */
	public boolean disabledAllotBtn() {
		boolean disabled = false;
		if(auto&&stationRoot!=null) {
			disabled = true;
		}
		if(manual&&deptIdToSelectedSubstations.size()>0&&deptIdToSelectedExperts.size()>0) {
			disabled = true;
		}
		return !disabled;
	}
	/**
	 * 分配专家
	 * 注：如果是已有专家的变电站也将重新被分配（即之前选择的专家将被覆盖）
	 */
	public void allot() {
		if(auto) {//一键分配
			Map<String,List<InspectionExpert>> result = new HashMap<String, List<InspectionExpert>>();
			for(String deptId : scopeIdToSubstations.keySet()) {
				allotOfOrder(scopeIdToSubstations.get(deptId),deptIdToExperts.get(deptId),expertNum,result);
			}
			for(String stationId : result.keySet()) {
				if(stationIdToExperts.containsKey(stationId)) {
					stationIdToExperts.remove(stationId);
				}
				stationIdToExperts.put(stationId, result.get(stationId));
			}
			addSuccessMessage("专家分配成功！");
		}else {//手动分配
			allotOfManual();				
		}
		
	}
	/**
	 * 手动分配
	 */
	private void allotOfManual() {
		List<Substation> targetStations = new ArrayList<Substation>();
		List<InspectionExpert> targetExperts = new ArrayList<InspectionExpert>();
		if(!deptIdToSelectedSubstations.isEmpty()) {
			for(String deptId : deptIdToSelectedSubstations.keySet()) {
				targetStations.addAll(deptIdToSelectedSubstations.get(deptId));
			}
		}
		if(targetStations.isEmpty()) {
			FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_WARN,"提示","请选择厂站！");
	    	PrimeFaces.current().dialog().showMessageDynamic(facesMsg);
			return;
		}
		if(!deptIdToSelectedExperts.isEmpty()) {
			for(String deptId : deptIdToSelectedExperts.keySet()) {
				targetExperts.addAll(deptIdToSelectedExperts.get(deptId));
			}
		}
		if(targetExperts.isEmpty()) {
			FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_WARN,"提示","请为选择的厂站选取专家！");
	    	PrimeFaces.current().dialog().showMessageDynamic(facesMsg);
			return;
		}
		Map<String,List<InspectionExpert>> result = new HashMap<String, List<InspectionExpert>>();
		allotOfOrder(targetStations,targetExperts,expertNum,result);
		for (String stationId : result.keySet()) {
			if(stationIdToExperts.containsKey(stationId)) {
				stationIdToExperts.remove(stationId);
			}
			stationIdToExperts.put(stationId, result.get(stationId));
		}
		addSuccessMessage("专家分配成功！");
	}
	/**
	 * 顺序分配
	 * @param stations
	 * @param experts
	 * @param num
	 * @param result
	 */
	private void allotOfOrder(List<Substation> stations,List<InspectionExpert> experts,int num,Map<String, List<InspectionExpert>> result) {
		if(stations!=null&&!stations.isEmpty()&&experts!=null&&!experts.isEmpty()) {
			int stationCount = stations.size();
			int expertCount = experts.size();
			//遍历选中的厂站，为其分配专家
			for(int i=0;i<stationCount;i++) {
				Substation currentStation = stations.get(i);
				List<InspectionExpert> expertList = new ArrayList<InspectionExpert>();
				if(expertCount>num) {//选择的专家人数大于指定人数
					int base = i*num;
					for(int j=0;j<num;j++) {
						int index = (base+j)%expertCount;
						expertList.add(experts.get(index));
					}
				}else {//选择的专家人数小于或等于指定人数
					expertList.addAll(experts);
				}
				result.put(currentStation.getId(), expertList);
			}
		}
	}
	/**
	 * 保存数据和关闭弹窗
	 */
	public void saveAndClose() {
		if(saveIsAvailable()) {
			List<InspectionStation> instations = new ArrayList<InspectionStation>();
			for(String scopeId : scopeIdToSubstations.keySet()) {
				ManagementUnitDict scope = maintenanceScopesMap.get(scopeId);
				for(Substation station : scopeIdToSubstations.get(scopeId)) {
					InspectionStation instation = new InspectionStation();
					instation.setAcceptScope(scope.getName());
					instation.setAcceptUnit(ledgerIdToMaintenanceUnitName.get(station.getId()));
					instation.setStationId(station.getId());
					instation.setStationName(station.getName());
					instation.setVoltagelevel(station.getStandVoltagelevel());
					List<InspectionExpert> experts = stationIdToExperts.get(station.getId());
					if(!experts.isEmpty()) {
						InspectionExpert expert = experts.get(0);
						instation.setInspectionExpertId(expert.getCode());
						instation.setInspectionExpert(expert.getName());
						instation.setInspectionExpertPhone(expert.getTelephone());
						instation.setInspectionUnit(expert.getDeptName());
					}
					instation.setInspectionItems(stationIdToInspectionItems.get(station.getId()));
					/**
					 * 设置变电站类型，待完善。。。
					 */
					if(stationIdToType.containsKey(station.getId())) {
						instation.setStationType(stationIdToType.get(station.getId()));
					}
					instations.add(instation);
				}
			}
			JSONObject r = new JSONObject();
			r.put("selectedInspectionStations", instations);
			data = r.toJSONString();
			PrimeFaces.current().executeScript("closeAndSave("+data+")");
		}

	}
	/**
	 * 是否可以保存
	 * @return
	 */
	private boolean saveIsAvailable() {
		if(substations.isEmpty()) {
			alertErrorMessage("未选择模板");
			return false;
		}
		for(Substation station : substations) {
			if(stationIdToExperts.containsKey(station.getId())) {
				List<InspectionExpert> expertList = stationIdToExperts.get(station.getId());
				if(expertList.isEmpty()) {
					alertErrorMessage("请为选择的厂站分配专家 ");
					return false;
				}
			}else {
				alertErrorMessage("请为选择的厂站分配专家 ");
				return false;
			}
		}
		return true;
	}

	public String getSelectedTempletId() {
		return selectedTempletId;
	}
	public void setSelectedTempletId(String selectedTempletId) {
		this.selectedTempletId = selectedTempletId;
	}
	public TreeNode getStationRoot() {
		return stationRoot;
	}
	public void setStationRoot(TreeNode stationRoot) {
		this.stationRoot = stationRoot;
	}
	public TreeNode[] getSelectedStationNodes() {
		return selectedStationNodes;
	}
	public void setSelectedStationNodes(TreeNode[] selectedStationNodes) {
		this.selectedStationNodes = selectedStationNodes;
	}
	public List<AssessmentTemplate> getTemplateList() {
		return templateList;
	}
	public void setTemplateList(List<AssessmentTemplate> templateList) {
		this.templateList = templateList;
	}
	
	public int getExpertNum() {
		return expertNum;
	}
	public void setExpertNum(int expertNum) {
		this.expertNum = expertNum;
	}
	public boolean isAuto() {
		return auto;
	}
	public void setAuto(boolean auto) {
		this.auto = auto;
	}
	public boolean isManual() {
		return manual;
	}
	public void setManual(boolean manual) {
		this.manual = manual;
	}
	public TreeNode getExpertRoot() {
		return expertRoot;
	}
	public void setExpertRoot(TreeNode expertRoot) {
		this.expertRoot = expertRoot;
	}
	public TreeNode[] getSelectedExpertNodes() {
		return selectedExpertNodes;
	}
	public void setSelectedExpertNodes(TreeNode[] selectedExpertNodes) {
		this.selectedExpertNodes = selectedExpertNodes;
	}
	public Date getStartTime() {
		return startTime;
	}
	public void setStartTime(Date startTime) {
		this.startTime = startTime;
	}
	public Date getEndTime() {
		return endTime;
	}
	public void setEndTime(Date endTime) {
		this.endTime = endTime;
	}
	
}
